<?php

namespace iBrand\Shop\Backend\Http\Controllers;

use iBrand\Shop\Backend\Service\CommonService;
use Encore\Admin\Facades\Admin;
use Encore\Admin\Layout\Content;
use iBrand\Component\Goods\Models\Goods;
use iBrand\Component\Goods\Models\Season;
use iBrand\Component\Goods\Models\SpecsValue;
use iBrand\Component\Goods\Models\Style;
use iBrand\Shop\Backend\Repository\O2oGoodsProductsRepository;
use iBrand\Shop\Backend\Repository\O2oGoodsRepository;
use iBrand\Store\Backend\Model\GoodsCategory;
use iBrand\Store\Backend\Repositories\BrandRepository;
use iBrand\Store\Backend\Repositories\CategoryRepository;
use iBrand\Component\Goods\Models\GoodsProduct;

class StockQueryController extends Controller
{
    protected $brandRepository;
    protected $categoryRepository;
    protected $o2oGoodsRepository;
    protected $o2oGoodsProductsRepository;
    protected $commonService;
    protected $cache;

    public function __construct(BrandRepository $brandRepository,
                                CategoryRepository $categoryRepository,
                                O2oGoodsRepository $o2oGoodsRepository,
                                O2oGoodsProductsRepository $o2oGoodsProductsRepository,
                                CommonService $commonService)
    {
        $this->brandRepository = $brandRepository;
        $this->categoryRepository = $categoryRepository;
        $this->o2oGoodsRepository = $o2oGoodsRepository;
        $this->o2oGoodsProductsRepository = $o2oGoodsProductsRepository;
        $this->commonService = $commonService;
        $this->cache = cache();
    }

    public function index()
    {
        $brandList = $this->commonService->getBrandList();
        $years = $this->commonService->getYearList();
        $categoryList = $this->commonService->getCategoryList();
        $specList = $this->commonService->getSpecList();
        $categories = $categoryList['categories'];
        $allCategories = $categoryList['allCategories'];
        $seasons = Season::all()->toArray();
        $styles = Style::all()->toArray();
        $colors = $specList['colors'];
        $sizes = $specList['sizes'];

        return Admin::content(function (Content $content) use ($brandList, $seasons, $styles, $categories, $allCategories, $years, $colors, $sizes) {

            $content->header('库存查询');

            $content->breadcrumb(
                ['text' => '库存查询', 'url' => '', 'no-pjax' => 1, 'left-menu-active' => '库存查询']
            );

            $content->body(view('shop-backend::stockQuery.index', compact('brandList', 'seasons', 'styles', 'categories', 'allCategories', 'years', 'colors', 'sizes')));
        });
    }

    public function getCategoryList($categories)
    {
        $result = [];
        $data = collect($categories);
        foreach ($categories as $category) {
            $children = $data->where('parent_id', $category['id']);
            if ($children->count() > 0) {
                $children = $children->values()->toArray();
                $tmp = [];
                foreach ($children as $value) {
                    $tmp[] = ['pTableVO' => $value, 'lstSubHierarchyVO' => []];
                }

                $result[] = ['pTableVO' => $category, 'lstSubHierarchyVO' => $tmp];
            } elseif ($children->count() <= 0 && !$category['parent_id']) {
                $result[] = ['pTableVO' => $category, 'lstSubHierarchyVO' => []];
            }
        }

        return $result;
    }

    public function getGoodsStoredList()
    {
        $condition = $this->queryConditions();
        $where = $condition[0];
        $ids = $condition[1];
        $where['status'] = 1;
        $goods = $this->o2oGoodsRepository->getGoodsPaginate($where, $ids, ['goods']);

        if ($goods->total() > 0) {
            foreach ($goods as $item) {
                $item->goodsId = $item->goods->id;
                $item->goodsName = $item->goods->name;
                $item->goodsSn = $item->goods->goods_no;
                $item->barCode = $item->goods->goods_barcode;
                $item->imagine = $item->goods->img;
                $item->colorId = $item->goods->colorIds;
                $item->sizeId = $item->goods->sizeIds;
                $item->seasonId = $item->goods->season_id;
                $item->seasonName = Season::where('id', $item->goods->season_id)->value('name');
                $item->styleName = Style::where('id', $item->goods->style_id)->value('name');
                $item->year = $item->goods->year;
                $item->blandId = $item->goods->brand_id;
                $item->categoryId = $item->goods->categories()->orderBy('id', 'DESC')->first()->id;
                $item->factoryPrice = $item->goods->factory_price;
                $item->tradePrice = $item->goods->market_price;
                $item->retailPriceArea = $item->goods->sell_price;
                $item->number = $item->store_nums;
            }
        }

        return $goods->toJson();
    }

    public function getGoodsSkuStoredList()
    {
        $condition = $this->queryConditions();
        $where = $condition[0];
        $ids = $condition[1];
        $goods = $this->o2oGoodsProductsRepository->getGoodsProductsPaginate($where, $ids, ['baseGoods', 'baseProduct']);

        if ($goods->total() > 0) {
            foreach ($goods as $item) {
                $item->goodsId = $item->baseGoods->id;
                $item->goodsName = $item->baseGoods->name;
                $item->goodsSn = $item->baseGoods->goods_no;
                $item->barCode = $item->baseGoods->goods_barcode;
                $item->imagine = $item->baseGoods->img;
                $item->skuSn = $item->baseProduct->sku;

                $tmpSpec = SpecsValue::find($item->baseProduct->specID[0]);
                if ($tmpSpec->spec_id == 1) {
                    $item->colorId = $item->baseProduct->specID[1];
                    $item->sizeId = $item->baseProduct->specID[0];
                } elseif ($tmpSpec->spec_id == 2) {
                    $item->colorId = $item->baseProduct->specID[0];
                    $item->sizeId = $item->baseProduct->specID[1];
                }

                $item->blandId = $item->baseGoods->brand_id;
                $item->categoryId = $item->baseGoods->categories()->orderBy('id', 'DESC')->first()->id;
                $item->factoryPrice = $item->baseGoods->factory_price;
                $item->tradePrice = $item->baseGoods->market_price;
                $item->retailPriceArea = $item->baseGoods->sell_price;
                $item->number = $item->store_nums;
            }
        }

        return $goods->toJson();
    }

    public function queryConditions()
    {
        $where['shop_id'] = session('shop_id');
        $search_goods_ids = [];
        $brand_search = false;
        $brand_goods_ids = [];

        if (request('zeroNumber')) {
            $where['store_nums'] = ['>', 0];
        }

        if (request('blandId')) {
            $brand_search = true;
            $goodsList = Goods::where('brand_id', request('blandId'))->get();
            if ($goodsList && $goodsList->count() > 0) {
                $brand_goods_ids = $goodsList->pluck('id')->toArray();
                sort($brand_goods_ids);
            }
        }

        $search_goods_ids[] = ['goods_ids' => $brand_goods_ids, 'is_search' => $brand_search];
        $style_search = false;
        $style_goods_ids = [];
        if (request('styleId')) {
            $style_search = true;
            $goodsList = Goods::where('style_id', request('styleId'))->get();
            if ($goodsList && $goodsList->count() > 0) {
                $style_goods_ids = $goodsList->pluck('id')->toArray();
                sort($style_goods_ids);
            }
        }

        $search_goods_ids[] = ['goods_ids' => $style_goods_ids, 'is_search' => $style_search];
        $year_search = false;
        $year_goods_ids = [];
        if (request('year')) {
            $year_search = true;
            $goodsList = Goods::where('year', request('year'))->get();
            if ($goodsList && $goodsList->count() > 0) {
                $year_goods_ids = $goodsList->pluck('id')->toArray();
                sort($year_goods_ids);
            }
        }

        $search_goods_ids[] = ['goods_ids' => $year_goods_ids, 'is_search' => $year_search];
        $season_search = false;
        $season_goods_ids = false;
        if (request('seasonId')) {
            $season_search = true;
            $goodsList = Goods::where('season_id', request('seasonId'))->get();
            if ($goodsList && $goodsList->count() > 0) {
                $season_goods_ids = $goodsList->pluck('id')->toArray();
                sort($season_goods_ids);
            }
        }

        $search_goods_ids[] = ['goods_ids' => $season_goods_ids, 'is_search' => $season_search];
        $a_is_search = false;
        $a_goods_ids = [];
        if (request('goodsName') && request('goodsSn')) {
            $a_is_search = true;
            $goods = Goods::where('name', 'like', '%' . request('goodsName') . '%')->orWhere('goods_no', 'like', '%' . request('goodsSn') . '%')->get();
            if ($goods && $goods->count() > 0) {
                $a_goods_ids = $goods->pluck('id')->toArray();
                $a_goods_ids = array_unique($a_goods_ids);
                sort($a_goods_ids);
            }
        }

        $search_goods_ids[] = ['goods_ids' => $a_goods_ids, 'is_search' => $a_is_search];
        $b_is_search = false;
        $b_goods_ids = [];
        /*if (request('skuSn') && 2 == request('listDataType')) {
            $b_is_search = true;
            $skuSn = GoodsProduct::where('is_show', 1)->where('sku', 'like', '%' . request('skuSn') . '%')->get();
            if ($skuSn && $skuSn->count() > 0) {
                $b_goods_ids = $skuSn->pluck('goods_id')->toArray();
                $b_goods_ids = array_unique($b_goods_ids);
                sort($b_goods_ids);
            }
        }*/

        $search_goods_ids[] = ['goods_ids' => $b_goods_ids, 'is_search' => $b_is_search];
        $c_is_search = false;
        $c_goods_ids = [];
        if (request('categoryId')) {
            $c_is_search = true;
            $category_goods = GoodsCategory::where('category_id', request('categoryId'))->get();
            if ($category_goods && $category_goods->count() > 0) {
                $c_goods_ids = $category_goods->pluck('goods_id')->toArray();
                $c_goods_ids = array_unique($c_goods_ids);
                sort($c_goods_ids);
            }
        }

        $search_goods_ids[] = ['goods_ids' => $c_goods_ids, 'is_search' => $c_is_search];
        $spec_goods_ids = [];
        $d_is_search = false;
        $tmpGoodsProduct = GoodsProduct::where('is_show', 1)->first();
        $tmpSpec = SpecsValue::find($tmpGoodsProduct->specID[0]);
        if ($tmpSpec->spec_id == 1) {
            $left_type = 'size';
        } elseif ($tmpSpec->spec_id == 2) {
            $left_type = 'color';
        }

        $product_ids = [];
        if (request('colorId') && !request('sizeId')) {
            $d_is_search = true;
            $like = $left_type == 'color' ? '["' . request('colorId') . '"%' : '%"' . request('colorId') . '"]';
            $products = GoodsProduct::where('is_show', 1)->where('specID', 'like', $like)->get();
            if ($products && $products->count() > 0) {
                $spec_goods_ids = $products->pluck('goods_id')->toArray();
                $product_ids = $products->pluck('id')->toArray();
            }
        } elseif (!request('colorId') && request('sizeId')) {
            $d_is_search = true;
            $like = $left_type == 'size' ? '["' . request('sizeId') . '"%' : '%"' . request('sizeId') . '"]';
            $products = GoodsProduct::where('is_show', 1)->where('specID', 'like', $like)->get();
            if ($products && $products->count() > 0) {
                $spec_goods_ids = $products->pluck('goods_id')->toArray();
                $product_ids = $products->pluck('id')->toArray();
            }
        } elseif (request('colorId') && request('sizeId')) {
            $d_is_search = true;
            $like = $left_type == 'color' ? '["' . request('colorId') . '","' . request('sizeId') . '"]' : '["' . request('sizeId') . '","' . request('colorId') . '"]';
            $products = GoodsProduct::where('is_show', 1)->where('specID', $like)->get();
            if ($products && $products->count() > 0) {
                $spec_goods_ids = $products->pluck('goods_id')->toArray();
                $product_ids = $products->pluck('id')->toArray();
            }
        }

        $where['goods']['product_ids'] = $product_ids;
        if (!empty($spec_goods_ids)) {
            $spec_goods_ids = array_unique($spec_goods_ids);
            sort($spec_goods_ids);
        }

        $search_goods_ids[] = ['goods_ids' => $spec_goods_ids, 'is_search' => $d_is_search];
        $ids = [];
        if (!empty($search_goods_ids)) {
            $collect_goods = collect($search_goods_ids);
            $filter_false_search = $collect_goods->filter(function ($item) {
                return $item['is_search'] === false;
            });

            if ($filter_false_search->count() != $collect_goods->count()) {
                $filter_empty_goods = $collect_goods->filter(function ($item) {
                    return $item['is_search'] && empty($item['goods_ids']);
                });

                if ($filter_empty_goods->count() <= 0) {
                    $filter_goods = $collect_goods->filter(function ($item) {
                        return $item['is_search'] && !empty($item['goods_ids']);
                    });

                    if ($filter_goods->count() > 0) {
                        $filter_goods = array_column($filter_goods->values()->toArray(), 'goods_ids');
                        $tmp = [];
                        $tmp_count = 0;
                        foreach ($filter_goods as $value) {
                            if (empty($tmp) && $tmp_count == 0) {
                                $tmp = $value;
                            } else {
                                $tmp = array_intersect($tmp, $value);
                            }

                            $tmp_count++;
                        }

                        if (!empty($tmp)) {
                            $ids = $tmp;
                        } else {
                            $ids = [0];
                        }
                    }
                } else {
                    $ids = [0];
                }
            }
        }

        $cacheFilter = [$where, $ids, $product_ids];
        $this->cache->put('export_shop_goods_filter', $cacheFilter, 30);
        return $cacheFilter;
    }

    public function getGoodsStoredSumData()
    {
        $condition = $this->queryConditions();
        $where = $condition[0];
        $ids = $condition[1];
        $store_nums = 0;
        $purchaseAmount = 0;

        $listDataType = request('listDataType');
        switch ($listDataType) {
            case 1 :
                $totalGoods = $this->o2oGoodsRepository->getGoodsPaginate($where, $ids, ['goods'], 0);
                if ($totalGoods->count()) {
                    $store_nums = $totalGoods->sum('store_nums');
                    foreach ($totalGoods as $good) {
                        $purchaseAmount += $good->store_nums * $good->goods->factory_price;
                    }
                }
                break;
            case 2 :
                $totalGoods = $this->o2oGoodsProductsRepository->getGoodsProductsPaginate($where, $ids, ['baseGoods', 'baseProduct'], 0);
                if ($totalGoods->count()) {
                    $store_nums = $totalGoods->sum('store_nums');
                    foreach ($totalGoods as $good) {
                        $purchaseAmount += $good->store_nums * $good->baseGoods->factory_price;
                    }
                }
                break;
        }

        return response()->json(['totalQuantity' => $store_nums, 'totalPurchaseAmount' => $purchaseAmount]);
    }

    public function getPhotosByGoodsId()
    {
        $goods_id = request('goodsId');

        $goods = Goods::find($goods_id);
        $photos = [];
        if ($goods) {
            $urls = $goods->photos()->pluck('url');
            if ($urls->count() > 0) {
                $photos = $urls->toArray();
            }
        }

        return $this->ajaxJson(true, $photos);
    }

    public function getExportData()
    {
        $page = request('page') ? request('page') : 1;
        $where = [];
        $ids = [];

        if ($this->cache->has('export_shop_goods_filter')) {
            $condition = $this->cache->get('export_shop_goods_filter');
            $where = $condition[0];
            $ids = $condition[1];
        }

        $goods = $this->o2oGoodsProductsRepository->getExcelGoods($where, $ids, ['baseGoods', 'baseProduct']);

        $lastPage = $goods['lastPage'];
        $goods = $goods['products'];
        $type = request('type');

        if ($page == 1) {
            /*$this->cache->forget('export_goods_cache');*/
            session(['export_shop_goods_cache' => generate_export_cache_name('export_shop_goods_cache_')]);
        }
        $cacheName = session('export_shop_goods_cache');

        if ($this->cache->has($cacheName)) {
            $cacheData = $this->cache->get($cacheName);
            $this->cache->put($cacheName, array_merge($cacheData, $goods), 300);
        } else {
            $this->cache->put($cacheName, $goods, 300);
        }

        if ($page == $lastPage) {
            $title = ['商品ID', 'SKU', '商品编号', '商品名称', '吊牌价', '采购价', '颜色', '尺码', '分类', '数量'];

            return $this->ajaxJson(true, ['status' => 'done', 'url' => '', 'type' => $type, 'title' => $title, 'cache' => $cacheName, 'prefix' => 'goods_data_']);
        } else {
            $url_bit = route('admin.shop.goods.getExportData', array_merge(['page' => $page + 1], request()->except('page')));

            return $this->ajaxJson(true, ['status' => 'goon', 'url' => $url_bit, 'page' => $page, 'totalPage' => $lastPage]);
        }
    }
}